#include<iostream>
using namespace std;
#include<pthread.h>
#include<unistd.h>
#define BUFFER_SIZE  20
/*定义锁*/
pthread_mutex_t g_mutex;
/*定义条件变量*/
pthread_cond_t g_notEmpty;
/*定义客户给老板条件变量*/
pthread_cond_t g_notFull;
/*链表节点*/
struct Node
{
    /*数据域*/
    int data;
    /*指针域*/
    Node* next;
};
/*链表的头结点*/
Node* g_head=NULL;

/*链表节点数量*/
int g_size=0;


/*生产者线程*/
void *thread_product(void*arg)
{
    /*线程分离*/
    pthread_detach(pthread_self());
    /*编号*/
    int number=1;
   
    
    while(1)
    {
         /*加锁*/
        pthread_mutex_lock(&g_mutex);

        while(g_size==BUFFER_SIZE )
        {
            /*阻塞等待条件变量*/
            pthread_cond_wait(&g_notFull,&g_mutex);
        }
        Node *newnode=new Node;
        newnode->data=number;
        newnode->next=g_head;
        g_head=newnode;

        /*链表个数++*/
        g_size++;

        /*解锁*/
        pthread_mutex_unlock(&g_mutex);
       
        printf("produce: %ld \tproduce %d,剩余%d张饼\n",pthread_self(),number,g_size);
         number++;
        /*通知食客开吃*/
        pthread_cond_signal(&g_notEmpty);

        /*休眠1s*/
        usleep(500000);
       
    }
    /*线程退出*/
    pthread_exit(NULL);
  

}

/*消费者线程*/
void *thread_consume(void *arg)
{
     /*线程分离*/
    pthread_detach(pthread_self());
    /*休眠10s*/
    sleep(20);
    while (1)
    {
        /*加锁*/
        pthread_mutex_lock(&g_mutex);

        //用while不用if的原因：条件变量可能造成虚假唤醒
        //例如，假设消费者线程被唤醒，但此时 g_head 仍然为空。
        //使用 if 判断条件只会在一次唤醒时判断一次，而有可能由于某些因素
        //（如其他线程的操作）导致消费者线程错误地继续执行，造成不一致的状态。
        while(g_head==NULL)
        {
            /*等待条件变量*/
            pthread_cond_wait(&g_notEmpty,&g_mutex);
            //1.解锁
            //2.等待信号
            //3.重新加锁
        }
        /*消费*/
        Node *consumeNode=g_head;
        g_head=g_head->next;

        /*链表个数--*/
        g_size--;


        /*锁的粒度*/
        //拿完一个立即把锁解开，否则生产者无法用这个锁
        pthread_mutex_unlock(&g_mutex);

        /*开吃*/
        printf("consumer=%ld,\teat=%d,还剩%d张饼\n",pthread_self(),consumeNode->data,g_size);
        sleep(2);

        /*发信号*/
        pthread_cond_signal(&g_notFull);
        /*释放推空间内存*/
        if(consumeNode!=NULL)
        {
         delete consumeNode;
         consumeNode=NULL;
        }

       
    }
    
    /*线程退出*/
    pthread_exit(NULL);
}
int main()
{
    /*创建生产者线程*/
    pthread_t  tid1;
    int ret=pthread_create(&tid1,NULL,thread_product,NULL);
    if(ret!=0)
    {
        cout<<"thread create error:"<<endl;
        _exit(-1);
    }
    /*创建消费者线程*/
    pthread_t  tid2;
    ret=pthread_create(&tid2,NULL,thread_consume,NULL);
    if(ret!=0)
    {
        cout<<"thread create error:"<<endl;
        _exit(-1);
    }
    int cnt=1000;
    while(cnt--)
    {
        sleep(1);
    }
    return 0;
}